//! 输出格式模块
//! 
//! 支持多种可执行文件格式输出

use crate::error::{AssemblerError, Result};

/// 输出文件格式
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutputFormat {
    /// 纯二进制文件 (.bin)
    Binary,
    /// DOS COM 可执行文件 (.com)
    Com,
    /// Windows PE 可执行文件 (.exe) - 待实现
    #[allow(dead_code)]
    Pe,
    /// Linux ELF 可执行文件 - 待实现
    #[allow(dead_code)]
    Elf,
}

impl OutputFormat {
    /// 根据文件扩展名确定输出格式
    pub fn from_extension(ext: &str) -> Result<Self> {
        match ext.to_lowercase().as_str() {
            "bin" => Ok(OutputFormat::Binary),
            "com" => Ok(OutputFormat::Com),
            "exe" => Ok(OutputFormat::Pe),
            "elf" => Ok(OutputFormat::Elf),
            _ => Err(AssemblerError::CodeGenError {
                message: format!("不支持的文件格式: .{}。支持格式: .bin, .com (未来: .exe, .elf)", ext),
            }),
        }
    }

    /// 获取格式名称
    pub fn name(&self) -> &'static str {
        match self {
            OutputFormat::Binary => "二进制文件",
            OutputFormat::Com => "DOS .COM 可执行文件",
            OutputFormat::Pe => "Windows PE 可执行文件",
            OutputFormat::Elf => "Linux ELF 可执行文件",
        }
    }

    /// 获取文件扩展名
    pub fn extension(&self) -> &'static str {
        match self {
            OutputFormat::Binary => "bin",
            OutputFormat::Com => "com",
            OutputFormat::Pe => "exe",
            OutputFormat::Elf => "elf",
        }
    }

    /// 检查文件大小限制
    pub fn check_size_limit(&self, size: usize) -> Result<()> {
        match self {
            OutputFormat::Com => {
                // .com 文件不能超过 64KB (65535 字节)
                if size > 65535 {
                    return Err(AssemblerError::CodeGenError {
                        message: format!(
                            "生成的代码太大 ({} 字节)，.com 文件不能超过 64KB (65535 字节)",
                            size
                        ),
                    });
                }
            }
            _ => {
                // 其他格式暂时没有大小限制
            }
        }
        Ok(())
    }

    /// 生成最终输出（根据格式处理）
    pub fn generate_output(&self, binary: &[u8]) -> Result<Vec<u8>> {
        match self {
            OutputFormat::Binary | OutputFormat::Com => {
                // .bin 和 .com 格式相同，都是纯二进制
                Ok(binary.to_vec())
            }
            OutputFormat::Pe => {
                Err(AssemblerError::CodeGenError {
                    message: "PE 格式支持尚未实现".to_string(),
                })
            }
            OutputFormat::Elf => {
                Err(AssemblerError::CodeGenError {
                    message: "ELF 格式支持尚未实现".to_string(),
                })
            }
        }
    }

    /// 获取输出目录（相对于 output 目录）
    pub fn output_directory(&self) -> &'static str {
        match self {
            OutputFormat::Binary => "",
            OutputFormat::Com => "com",
            OutputFormat::Pe => "pe",
            OutputFormat::Elf => "elf",
        }
    }
}

